1 Abstract

This study is about the H-1B visa petitions filed by employers during Fiscal Year 2024.This project mainly performs the descriptive statistics, exploratory data analysis, and statistical tests. The main focus will be on the areas of finding the Top statistics related to geographic locations, industries and validating the hypothesis of whether there is any relation between the company filings count and approvals. The key findings I found are primarily NACIS codes which is related to Information Technology and software companies ranks the highest in offering the H1B sponsored Job opportunities. Further analysis showed a high concentration of petitioning employers in specific states, like California, Texas, New Jersey, New York, and Virginia. A Chi-squared test demonstrated a statistically significant association between the volume of initial petitions filed by an employer and their approval rate, with employers filing more petitions (‘Large Filers’) experiencing higher approval rates than those filing fewer (‘Small Filers’). Overall, the FY2024 data suggests that H-1B sponsorship is concentrated geographically and by industry, and that higher petition volume correlates with higher initial success rates.

2 Introduction

The H-1B visa program plays a significant role in the United States economy, it helps employers to temporarily employ foreign workers in specialized occupations. For many international students studying in the United States, securing post-graduation employment often involves the complex H-1B visa process, frequently as a transition from Optional Practical Training (OPT) or Curricular Practical Training (CPT). Understanding the trends of H-1B sponsorship is therefore vital for career planning and decision-making. This analysis mainly looks at identifying companies and industries most actively sponsoring H-1B visas in FY2024, finding the top geographic locations where H-1B opportunities are concentrated. Investigating this is crucial for international students because it helps identify potential employers willing to sponsor, highlights promising geographic areas for job searching, provides realistic salary expectations.

To explore this, I taken the Fiscal year 2024 data set from the publicly available dataset at the H1B Employer Datahub

This data set contains the approval and denial records of H-1B visa applications. The counts of initial approval, initial denial, continuing approval, and continuing denial are aggregated by distinct completion fiscal year, two digit NAICS code, tax ID, state, city, and ZIP code.

More Details at: Understanding Our H-1B Employer Data Hub

3 Data Management

3.1 Data Import

Below represents the glimpse of raw data taken from the H1B Employer Hub

## Rows: 61,456
## Columns: 12
## $ Line.by.line               <chr> "1", "2", "3", "4", "5", "6", "7", "8", "9"…
## $ Fiscal.Year                <int> 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2…
## $ Employer..Petitioner..Name <chr> "", "", "1 800 FLOWERS COM INC", "1 HOTEL K…
## $ Tax.ID                     <int> 3581, 4245, 7311, 5669, 7999, 6496, 3805, 1…
## $ Industry..NAICS..Code      <chr> "54 - Professional, Scientific, and Technic…
## $ Petitioner.City            <chr> "LAFAYETTE", "DAVIE", "JERICHO", "MIAMI", "…
## $ Petitioner.State           <chr> "CA", "FL", "NY", "FL", "OR", "SC", "CA", "…
## $ Petitioner.Zip.Code        <int> 94549, 33328, 11753, 33133, 97367, 29708, 9…
## $ Initial.Approval           <chr> "0", "1", "1", "0", "1", "1", "1", "0", "0"…
## $ Initial.Denial             <int> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0…
## $ Continuing.Approval        <chr> "1", "0", "5", "1", "0", "1", "0", "1", "3"…
## $ Continuing.Denial          <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…

3.2 Data Cleaning and Manipulation

I have performed following operations to clean the data and make it ready for the further analysis.

  • I simplified and renamed the columns to make them clearer using select().

  • I also replaced empty strings with NA and changed any NA values in the approval/denial columns to 0 using na_if() and coalesce().

  • I removed rows with missing Tax_ID or Employer_Name, and also removed rows where all the approval/denial values were zero.

  • I added new columns for the total H1Bs, new H1Bs, and renewal H1Bs using mutate().

3.3 Final Dataset

3.4 Variable Definitions

  • Employer_Name – Name of the employer submitting the H1B petition.
  • Tax_ID – A unique tax identifier assigned to each employer.
  • NACIS_CODE – North American Industry Classification System code indicating the industry type.
  • Petitioner_City – The city where the petitioning employer is located.
  • Petitioner_State – The US state corresponding to the employer’s location.
  • Petitioner_Zip – ZIP code of the petitioning employer.
  • Initial_Approval – Number of new H1B visa petitions that were initially approved.
  • Initial_Denial – Number of new H1B visa petitions that were denied.
  • Continuing_Approval – Number of extensions or renewals approved for existing H1B visas.
  • Continuing_Denial – Number of continuing H1B petitions denied.
  • Total_H1B – The total number of H1B petitions submitted (new + renewals).
  • Total_Lottery_H1B – Total count of newly submitted H1B petitions.
  • Total_Other – Total count of H1B visa extensions or renewals submitted.

3.5 Key Terms

  • H-1B Visa: Employment visa for specialized foreign workers
  • H1B Lottery: The H-1B lottery is a random selection process USCIS uses when the number of applications for new H-1B work visas exceeds the 85,000 available visa slots. Being selected in this lottery is necessary before an employer can formally file the full H-1B petition for a cap-subject employee.
  • Initial vs Continuing: Initial applications stands for new applications whereas continuing applications contains cases when people change employers, any details etc
  • Petitioner: Employer sponsoring the visa application
  • Tax_ID: The Employer Identification Number (EIN), a unique identifier assigned by the IRS
  • NACIS_CODE: North American Industry Classification System code. This numeric code identifies the primary industry sector of the employer (e.g., Software Publishers, Computer Systems Design, Colleges/Universities).

3.6 Initial Exploratory Data Analysis

3.6.1 Numeric Variable Analysis

3.6.1.1 center and spread of Numeric variables

Summary Statistics for Numeric Petition Counts
variable n min max median q1 q3 iqr mad mean sd se ci
Initial_Approval 52775 0 918 1 0 1 1 1.483 2.406 14.820 0.065 0.126
Initial_Denial 52775 0 87 0 0 0 0 0.000 0.068 0.643 0.003 0.005
Continuing_Approval 52775 0 977 1 0 2 2 1.483 3.680 20.008 0.087 0.171
Continuing_Denial 52775 0 179 0 0 0 0 0.000 0.087 1.268 0.006 0.011
Total_H1B 52775 1 1431 1 1 3 2 0.000 6.241 30.795 0.134 0.263
Total_Lottery_H1B 52775 0 922 1 0 1 1 1.483 2.474 14.978 0.065 0.128
Total_Other 52775 0 1045 1 0 2 2 1.483 3.767 20.392 0.089 0.174

The median for most count variables is low, while the mean is significantly higher. The standard deviations and the IQR are large relative to the medians, further confirming the wide spread and skewness. So the summary statistics show H1B petition counts are strongly right-skewed with a wide spread. This means most employers file very few petitions, while a small number file extremely high volumes. These high-volume outliers appear genuine and represent significant H1B activity, so they should be retained in the analysis.

3.6.1.2 Histogram for each numeric variable

The histograms confirm the distributions are heavily right-skewed. Even on the log scale, we see most of the frequency concentrated towards the lower counts i.e In the summary if you observe for all categories the Mean is greater than Medians. Means most employers file very few H1B petitions but a smaller number of employers file a very large number of petitions, pulling the average up.The use of the log scale was essential to visualize this distribution.

3.6.1.3 Boxplots for each numeric variable

The main box (IQR) for each variable is compressed near the bottom, indicating that 50% of employers fall within a narrow range of low counts. There’s a wide variation in H1B filing activity among employers. The numerous outliers represent employers with exceptionally high petition volumes compared to the typical filer. As discussed before, these are usually genuine (like large tech companies, consulting firms, universities) and represent a significant portion of the total H1B activity.

3.6.2 Categorical Variable Analysis

3.6.2.1 Frequency table by state

3.6.2.2 Frequency table by city

3.6.2.3 Frequency table by Zipcode

3.6.2.4 Frequency table by NACIS code

3.6.2.5 Petitioner State Map

The above Map shows states with frequencies of H1B petitions

3.6.2.6 Petitioner State Analysis

The bar chart show the states with the highest number of unique employers filing H1B petitions in FY2024. The states like California, Texas, New Jersey, New York, and Virginia appearing frequently.

3.6.2.7 Petitioner Cities Analysis

This analysis reveals the specific cities where the highest number of employers filing H1B petitions are located in New York, San Francisco, Houston, etc

3.6.2.8 Petitioner Zipcode Analysis

The top zip codes often points to specific corporate campuses, office parks, or university areas known for high concentrations of H1B employers. For example, you might see zip codes associated with major tech company headquarters or large consulting firm offices appearing frequently.

3.6.2.9 NAICS codes Analysis

The chart show the most frequent NAICS codes associated with employers filing H1B petitions. Codes related to IT services (like Custom Computer Programming Services - often 541511, Computer Systems Design Services - 541512), Software Publishing (511210), Management Consulting (541611), and potentially higher education or research often dominate. Also surprisingly there are lot of employers(it ranks on 7th position) who doesn’t have the NAICS code or it is missing in the input raw data

For more details related to NAICS code- https://www.census.gov/naics/

4 Analysis

I am analyzing the H1B FY2024 data to check whether there is a statistically significant relation between the size of the petitioning company and the outcome of initial H1B petitions (Approval vs. Denial).

Company size is not available in the data set so I’m assuming the total number of initial H1B petitions filed by each unique employer as an identifier to decide the company size. We will categorize employers based on whether they are above or below the median number of petitions filed and use a Chi-squared test of independence to compare approval rates between these groups.

Number of Employers per Size Category
Var1 Freq
Large Filer 13004
Small Filer 39771
Aggregated Counts for Chi-squared Test
Size_Category Total_Initial_Approved Total_Initial_Denied
Small Filer 18307 621
Large Filer 108672 2983

From the median, we got to know there are 13004 Large filers(Big Companies, universities etc) and 39771 smaller filers(Start ups, Newly entered into H1B’s)

4.1 Chi-squared Test of Independence

We perform the Chi-squared test to determine if there’s a statistically significant association between the company size category and the initial petition outcome.

Hypotheses:

  • H₀: The initial petition outcome (Approval/Denial) is independent of the company size category.
  • H₁: The initial petition outcome (Approval/Denial) is dependent on the company size category.

Assumptions:

  • Categorical Data: Size_Category (Small/Large Filer) and Outcome (Approval/Denial).
  • Independence of Observations: Assumed for each petition.
  • Expected Cell Counts: All expected frequencies should be ≥ 5.
## 
##  Pearson's Chi-squared test with simulated p-value (based on 5000
##  replicates)
## 
## data:  contingency_table
## X-squared = 22.383, df = NA, p-value = 2e-04
##             Total_Initial_Approved Total_Initial_Denied
## Small Filer                18405.6             522.3996
## Large Filer               108573.4            3081.6004
## 
## Assumption Check: Are all expected counts >= 5? TRUE

The Chi-squared test results based on the p-value and significance level (alpha=0.05).

Decision: Since the p-value ( 2e-04 ) is less than alpha ( 0.05 ), we reject the null hypothesis (H₀).

Conclusion:

There is a statistically significant association between the company size category (Small Filer vs. Large Filer, based on petition volume) and the initial H1B petition outcome (Approval/Denial) at the 5% significance level.

The analysis suggests that the likelihood of an initial H1B petition being approved differs significantly between companies filing fewer petitions (<= 1, ‘Small Filers’) and those filing more (‘> 1’, ‘Large Filers’).

This indicates that companies filing a larger volume of initial H1B petitions tend to have a higher approval rate compared to those filing fewer petitions.

5 Summary

This project analyzed H-1B visa petition data for FY 2024 to understand current trends in employer sponsorship, focusing on identifying which types of companies and locations are most active and whether company size relates to petition success.

Key Findings:

  • H-1B petitioning activity is more in specific states, with California, Texas, New Jersey, New York, and Virginia showing the highest number of unique employers filing petitions. Major metropolitan areas within these states are hotspots.

  • Industries related to Information Technology are overwhelmingly the most common sectors for employers filing H-1B petitions.

  • Our statistical analysis investigated whether the number of petitions a company files (used as an indicator of its size or H-1B activity level) is related to its success in getting initial petitions approved. We found Companies that filed a larger number of initial H-1B petitions (classified as ‘Large Filers’ based on filing more than the median number) generally had a higher initial approval rate compared to companies filing fewer petitions (‘Small Filers’).

  • This suggests that employers with higher H-1B petition volumes tend to experience greater success rates for their initial applications, although the difference in percentage points might be relatively small.

Limitations:

  • A key limitation was using the number of petitions filed as a proxy for actual company size. While its related, this isn’t a perfect measure. A company could file many petitions but still be relatively small, or vice-versa.

  • Employer Identification: Grouping data relied on employer names. Minor differences in how names were recorded could potentially split a single company into multiple entries, slightly affecting counts(EX: AMAZON DEVELOPMENT CENTER U S INC, AMAZON DATA SERVICES INC, AMAZON COM SERVICES LLC etc)

  • This analysis is a snapshot based on FY2024 data. It doesn’t show trends over multiple years or provide reasons why petitions were approved or denied.

Next Steps:

  • If possible, adding the company employee counts could provide a more accurate comparison based on company size.

  • Repeating the size vs. approval rate analysis within specific dominant industries (like IT) or states (like California) could reveal if this trend holds true across different segments.

  • Investigating if a similar relationship exists between company size/petition volume and the success rate of continuing (renewal) petitions.

  • using FY2024 as sample, we can do similar analysis on history of all Fiscal years data to get more findings.

7 Personal Information

Geethakrishna Puligundla (GK) is graduating in May 2025 with Masters in Computer Science degree. He is a nerd guy likes to work with nuanced things. He likes to go into rabbit hole(deep research) if he feels its exciting. Interested to work on the building new products/software to make it helpful for the society and strive for making the world a better place. Currently looking for a new opportunity to work on after graduation.

His philosophy is to “Be curious! Solve hard problems”

mail:

LS0tDQp0aXRsZTogIkgtMUIgRGF0YSBBbmFseXNpcyhGWTI0KSINCmF1dGhvcjogIkdlZXRoYWtyaXNobmEgUHVsaWd1bmRsYSINCmRhdGU6ICIyMDI1LTA0LTI5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiBqb3VybmFsDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBlY2hvID0gRkFMU0UsICAgICAgICMgaGlkZSBjb2RlIGJ5IGRlZmF1bHQNCiAgd2FybmluZyA9IEZBTFNFLCAgICAjIHN1cHByZXNzIHdhcm5pbmdzDQogIG1lc3NhZ2UgPSBGQUxTRSwgICAgIyBzdXBwcmVzcyBtZXNzYWdlcw0KICBmaWcuYWxpZ24gPSAnY2VudGVyJywgIyBjZW50ZXJzIHRoZSBmaWcNCiAgZmlnLndpZHRoID0gNywNCiAgZmlnLmhlaWdodCA9IDUsDQogIGRwaSA9IDMwMCwNCiAgb3V0LndpZHRoID0gJzkwJScNCikNCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJzdGF0aXgpICMgRm9yIGdldF9zdW1tYXJ5X3N0YXRzDQpsaWJyYXJ5KHNjYWxlcykgICMgRm9yIHBsb3QgbGFiZWxzDQpsaWJyYXJ5KHBsb3RseSkgICMgRm9yIGludGVyYWN0aXZlIHBsb3RzDQpsaWJyYXJ5KERUKSAgICAgICMgRm9yIGludGVyYWN0aXZlIHRhYmxlcw0KbGlicmFyeShrbml0cikgICAjIEZvciBrYWJsZSB0YWJsZXMNCmxpYnJhcnkoa2FibGVFeHRyYSkgIyBGb3Igc3R5bGluZyBrYWJsZSB0YWJsZXMNCmBgYA0KDQpgYGB7Y3NzLCBlY2hvPUZBTFNFfQ0KcCwgbGkgew0KICB0ZXh0LWFsaWduOiBqdXN0aWZ5Ow0KfQ0KDQogcCB7IG1hcmdpbi1ib3R0b206IDFlbTsgfSAqLw0KDQpgYGANCg0KIyBBYnN0cmFjdA0KDQpUaGlzIHN0dWR5IGlzIGFib3V0IHRoZSBILTFCIHZpc2EgcGV0aXRpb25zIGZpbGVkIGJ5IGVtcGxveWVycyBkdXJpbmcgRmlzY2FsIFllYXIgMjAyNC5UaGlzIHByb2plY3QgbWFpbmx5IHBlcmZvcm1zIHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLCBleHBsb3JhdG9yeSBkYXRhIGFuYWx5c2lzLCBhbmQgc3RhdGlzdGljYWwgdGVzdHMuIFRoZSBtYWluIGZvY3VzIHdpbGwgYmUgb24gdGhlIGFyZWFzIG9mIGZpbmRpbmcgdGhlIFRvcCBzdGF0aXN0aWNzIHJlbGF0ZWQgdG8gZ2VvZ3JhcGhpYyBsb2NhdGlvbnMsIGluZHVzdHJpZXMgYW5kIHZhbGlkYXRpbmcgdGhlIGh5cG90aGVzaXMgb2Ygd2hldGhlciB0aGVyZSBpcyBhbnkgcmVsYXRpb24gYmV0d2VlbiB0aGUgY29tcGFueSBmaWxpbmdzIGNvdW50IGFuZCBhcHByb3ZhbHMuIFRoZSBrZXkgZmluZGluZ3MgSSBmb3VuZCBhcmUgcHJpbWFyaWx5IE5BQ0lTIGNvZGVzIHdoaWNoIGlzIHJlbGF0ZWQgdG8gKipJbmZvcm1hdGlvbiBUZWNobm9sb2d5IGFuZCBzb2Z0d2FyZSBjb21wYW5pZXMqKiByYW5rcyB0aGUgaGlnaGVzdCBpbiBvZmZlcmluZyB0aGUgSDFCIHNwb25zb3JlZCBKb2Igb3Bwb3J0dW5pdGllcy4gRnVydGhlciBhbmFseXNpcyBzaG93ZWQgKiphIGhpZ2ggY29uY2VudHJhdGlvbiBvZiBwZXRpdGlvbmluZyBlbXBsb3llcnMgaW4gc3BlY2lmaWMgc3RhdGVzLCBsaWtlIENhbGlmb3JuaWEsIFRleGFzLCBOZXcgSmVyc2V5LCBOZXcgWW9yaywgYW5kIFZpcmdpbmlhKiouIEEgQ2hpLXNxdWFyZWQgdGVzdCBkZW1vbnN0cmF0ZWQgYSAqKnN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgdm9sdW1lIG9mIGluaXRpYWwgcGV0aXRpb25zIGZpbGVkIGJ5IGFuIGVtcGxveWVyIGFuZCB0aGVpciBhcHByb3ZhbCByYXRlKiosIHdpdGggZW1wbG95ZXJzIGZpbGluZyBtb3JlIHBldGl0aW9ucyAoJ0xhcmdlIEZpbGVycycpIGV4cGVyaWVuY2luZyBoaWdoZXIgYXBwcm92YWwgcmF0ZXMgdGhhbiB0aG9zZSBmaWxpbmcgZmV3ZXIgKCdTbWFsbCBGaWxlcnMnKS4gT3ZlcmFsbCwgdGhlIEZZMjAyNCBkYXRhIHN1Z2dlc3RzIHRoYXQgSC0xQiBzcG9uc29yc2hpcCBpcyBjb25jZW50cmF0ZWQgZ2VvZ3JhcGhpY2FsbHkgYW5kIGJ5IGluZHVzdHJ5LCBhbmQgdGhhdCBoaWdoZXIgcGV0aXRpb24gdm9sdW1lIGNvcnJlbGF0ZXMgd2l0aCBoaWdoZXIgaW5pdGlhbCBzdWNjZXNzIHJhdGVzLg0KDQoNCiMgSW50cm9kdWN0aW9uDQoNCiFbXShoMWJfcGljLnBuZykNCg0KVGhlIEgtMUIgdmlzYSBwcm9ncmFtIHBsYXlzIGEgc2lnbmlmaWNhbnQgcm9sZSBpbiB0aGUgVW5pdGVkIFN0YXRlcyBlY29ub215LCBpdCBoZWxwcyBlbXBsb3llcnMgdG8gdGVtcG9yYXJpbHkgZW1wbG95IGZvcmVpZ24gd29ya2VycyBpbiBzcGVjaWFsaXplZCBvY2N1cGF0aW9ucy4gRm9yIG1hbnkgaW50ZXJuYXRpb25hbCBzdHVkZW50cyBzdHVkeWluZyBpbiB0aGUgVW5pdGVkIFN0YXRlcywgc2VjdXJpbmcgcG9zdC1ncmFkdWF0aW9uIGVtcGxveW1lbnQgb2Z0ZW4gaW52b2x2ZXMgdGhlIGNvbXBsZXggSC0xQiB2aXNhIHByb2Nlc3MsIGZyZXF1ZW50bHkgYXMgYSB0cmFuc2l0aW9uIGZyb20gT3B0aW9uYWwgUHJhY3RpY2FsIFRyYWluaW5nIChPUFQpIG9yIEN1cnJpY3VsYXIgUHJhY3RpY2FsIFRyYWluaW5nIChDUFQpLiBVbmRlcnN0YW5kaW5nIHRoZSB0cmVuZHMgb2YgSC0xQiBzcG9uc29yc2hpcCBpcyB0aGVyZWZvcmUgdml0YWwgZm9yIGNhcmVlciBwbGFubmluZyBhbmQgZGVjaXNpb24tbWFraW5nLiBUaGlzIGFuYWx5c2lzIG1haW5seSBsb29rcyBhdCBpZGVudGlmeWluZyBjb21wYW5pZXMgYW5kIGluZHVzdHJpZXMgbW9zdCBhY3RpdmVseSBzcG9uc29yaW5nIEgtMUIgdmlzYXMgaW4gRlkyMDI0LCBmaW5kaW5nIHRoZSB0b3AgZ2VvZ3JhcGhpYyBsb2NhdGlvbnMgd2hlcmUgSC0xQiBvcHBvcnR1bml0aWVzIGFyZSBjb25jZW50cmF0ZWQuIEludmVzdGlnYXRpbmcgdGhpcyBpcyBjcnVjaWFsIGZvciBpbnRlcm5hdGlvbmFsIHN0dWRlbnRzIGJlY2F1c2UgaXQgaGVscHMgaWRlbnRpZnkgcG90ZW50aWFsIGVtcGxveWVycyB3aWxsaW5nIHRvIHNwb25zb3IsIGhpZ2hsaWdodHMgcHJvbWlzaW5nIGdlb2dyYXBoaWMgYXJlYXMgZm9yIGpvYiBzZWFyY2hpbmcsIHByb3ZpZGVzIHJlYWxpc3RpYyBzYWxhcnkgZXhwZWN0YXRpb25zLg0KDQpUbyBleHBsb3JlIHRoaXMsIEkgdGFrZW4gdGhlIEZpc2NhbCB5ZWFyIDIwMjQgZGF0YSBzZXQgZnJvbSB0aGUgcHVibGljbHkgYXZhaWxhYmxlIGRhdGFzZXQgYXQgdGhlIFtIMUIgRW1wbG95ZXIgRGF0YWh1Yl0oaHR0cHM6Ly93d3cudXNjaXMuZ292L3Rvb2xzL3JlcG9ydHMtYW5kLXN0dWRpZXMvaC0xYi1lbXBsb3llci1kYXRhLWh1YikNCg0KVGhpcyBkYXRhIHNldCBjb250YWlucyB0aGUgYXBwcm92YWwgYW5kIGRlbmlhbCByZWNvcmRzIG9mIEgtMUIgdmlzYSBhcHBsaWNhdGlvbnMuIFRoZSBjb3VudHMgb2YgaW5pdGlhbCBhcHByb3ZhbCwgaW5pdGlhbCBkZW5pYWwsIGNvbnRpbnVpbmcgYXBwcm92YWwsIGFuZCBjb250aW51aW5nIGRlbmlhbCBhcmUgYWdncmVnYXRlZCBieSBkaXN0aW5jdCBjb21wbGV0aW9uIGZpc2NhbCB5ZWFyLCB0d28gZGlnaXQgTkFJQ1MgY29kZSwgdGF4IElELCBzdGF0ZSwgY2l0eSwgYW5kIFpJUCBjb2RlLg0KDQpNb3JlIERldGFpbHMgYXQ6IFtVbmRlcnN0YW5kaW5nIE91ciBILTFCIEVtcGxveWVyIERhdGEgSHViXShodHRwczovL3d3dy51c2Npcy5nb3YvdG9vbHMvcmVwb3J0cy1hbmQtc3R1ZGllcy9oLTFiLWVtcGxveWVyLWRhdGEtaHViL3VuZGVyc3RhbmRpbmctb3VyLWgtMWItZW1wbG95ZXItZGF0YS1odWIpDQoNCiMgRGF0YSBNYW5hZ2VtZW50DQoNCiMjIERhdGEgSW1wb3J0DQoNCkJlbG93IHJlcHJlc2VudHMgdGhlIGdsaW1wc2Ugb2YgcmF3IGRhdGEgdGFrZW4gZnJvbSB0aGUgSDFCIEVtcGxveWVyIEh1Yg0KDQpgYGB7ciBkYXRhLWltcG9ydH0NCmgxYl9kYXRhIDwtICByZWFkLmNzdigiRW1wbG95ZXJfSW5mb3JtYXRpb25fRjI0LmNzdiIpDQpnbGltcHNlKGgxYl9kYXRhKQ0KYGBgDQoNCiMjIERhdGEgQ2xlYW5pbmcgYW5kIE1hbmlwdWxhdGlvbg0KDQpgYGB7ciBkYXRhLWNsZWFuaW5nLCBpbmNsdWRlPUZBTFNFfQ0KDQojIHNlbGVjdGluZyBuZWNlc3NhcnkgYXR0cmlidXRlcyBhbmQgcmVuYW1pbmcNCmgxYl9kYXRhIDwtIGgxYl9kYXRhICU+JQ0KICBzZWxlY3QoDQogICAgRW1wbG95ZXJfTmFtZSA9IEVtcGxveWVyLi5QZXRpdGlvbmVyLi5OYW1lLA0KICAgIFRheF9JRCA9IFRheC5JRCwNCiAgICBOQUNJU19DT0RFID0gSW5kdXN0cnkuLk5BSUNTLi5Db2RlLA0KICAgIFBldGl0aW9uZXJfQ2l0eSA9IFBldGl0aW9uZXIuQ2l0eSwNCiAgICBQZXRpdGlvbmVyX1N0YXRlID0gUGV0aXRpb25lci5TdGF0ZSwNCiAgICBQZXRpdGlvbmVyX1ppcCA9IFBldGl0aW9uZXIuWmlwLkNvZGUsDQogICAgSW5pdGlhbF9BcHByb3ZhbCA9IEluaXRpYWwuQXBwcm92YWwsDQogICAgSW5pdGlhbF9EZW5pYWwgPSBJbml0aWFsLkRlbmlhbCwNCiAgICBDb250aW51aW5nX0FwcHJvdmFsID0gQ29udGludWluZy5BcHByb3ZhbCwNCiAgICBDb250aW51aW5nX0RlbmlhbCA9IENvbnRpbnVpbmcuRGVuaWFsDQogICkNCg0KIyByZW1vdmluZyB0aGUgbnVsbHMNCmgxYl9kYXRhIDwtIGgxYl9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgRW1wbG95ZXJfTmFtZSA9IG5hX2lmKEVtcGxveWVyX05hbWUsICIiKSwNCiAgICBJbml0aWFsX0FwcHJvdmFsID0gY29hbGVzY2UoYXMuaW50ZWdlcihJbml0aWFsX0FwcHJvdmFsKSwgMCksDQogICAgSW5pdGlhbF9EZW5pYWwgPSBjb2FsZXNjZShhcy5pbnRlZ2VyKEluaXRpYWxfRGVuaWFsKSwgMCksDQogICAgQ29udGludWluZ19BcHByb3ZhbCA9IGNvYWxlc2NlKGFzLmludGVnZXIoQ29udGludWluZ19BcHByb3ZhbCksIDApLA0KICAgIENvbnRpbnVpbmdfRGVuaWFsID0gY29hbGVzY2UoYXMuaW50ZWdlcihDb250aW51aW5nX0RlbmlhbCksIDApDQopDQoNCiMgZmlsdGVyaW5nIHRoZSB2YWxpZCByZWNvcmRzDQpoMWJfZGF0YSA8LSBoMWJfZGF0YSAlPiUNCiAgIyBSZW1vdmUgcm93cyB3aXRoIG1pc3NpbmcgVGF4X0lEIG9yIEVtcGxveWVyX05hbWUNCiAgZmlsdGVyKCFpcy5uYShFbXBsb3llcl9OYW1lKSwgIWlzLm5hKFRheF9JRCksICFpcy5uYShQZXRpdGlvbmVyX1ppcCkpICU+JQ0KICANCiAgIyBSZW1vdmUgcm93cyB3aGVyZSBhbGwgYXBwcm92YWwvZGVuaWFsIGNvdW50cyBhcmUgMA0KICBmaWx0ZXIoIShJbml0aWFsX0FwcHJvdmFsID09IDAgJiBJbml0aWFsX0RlbmlhbCA9PSAwICYgDQogICAgICAgICAgIENvbnRpbnVpbmdfQXBwcm92YWwgPT0gMCAmIENvbnRpbnVpbmdfRGVuaWFsID09IDApKQ0KDQojIGdyb3VwaW5nIHRoZSBkdXBsaWNhdGUgcmVjb3Jkcw0KaDFiX2RhdGEgPC0gaDFiX2RhdGEgJT4lDQogIGdyb3VwX2J5KEVtcGxveWVyX05hbWUpICU+JQ0KICBzdW1tYXJpemUoDQogICAgVGF4X0lEID0gZmlyc3QobmEub21pdChUYXhfSUQpKSwNCiAgICBOQUNJU19DT0RFID0gZmlyc3QobmEub21pdChOQUNJU19DT0RFKSksDQogICAgUGV0aXRpb25lcl9DaXR5ID0gZmlyc3QobmEub21pdChQZXRpdGlvbmVyX0NpdHkpKSwNCiAgICBQZXRpdGlvbmVyX1N0YXRlID0gZmlyc3QobmEub21pdChQZXRpdGlvbmVyX1N0YXRlKSksDQogICAgUGV0aXRpb25lcl9aaXAgPSBmaXJzdChuYS5vbWl0KFBldGl0aW9uZXJfWmlwKSksDQogICAgSW5pdGlhbF9BcHByb3ZhbCA9IHN1bShJbml0aWFsX0FwcHJvdmFsKSwNCiAgICBJbml0aWFsX0RlbmlhbCA9IHN1bShJbml0aWFsX0RlbmlhbCksDQogICAgQ29udGludWluZ19BcHByb3ZhbCA9IHN1bShDb250aW51aW5nX0FwcHJvdmFsKSwNCiAgICBDb250aW51aW5nX0RlbmlhbCA9IHN1bShDb250aW51aW5nX0RlbmlhbCksDQogICAgLmdyb3VwcyA9ICdkcm9wJyAgIyBUbyB1bmdyb3VwIGFmdGVyIHN1bW1hcml6aW5nDQogICkNCg0KIyBhZGRpbmcgbmV3IGNvbHVtbnMNCmgxYl9kYXRhIDwtIGgxYl9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgVG90YWxfSDFCID0gSW5pdGlhbF9BcHByb3ZhbCArIEluaXRpYWxfRGVuaWFsICsgQ29udGludWluZ19BcHByb3ZhbCArIENvbnRpbnVpbmdfRGVuaWFsLA0KICAgIFRvdGFsX0xvdHRlcnlfSDFCID0gSW5pdGlhbF9BcHByb3ZhbCArIEluaXRpYWxfRGVuaWFsLA0KICAgIFRvdGFsX090aGVyID0gQ29udGludWluZ19BcHByb3ZhbCArIENvbnRpbnVpbmdfRGVuaWFsDQogICkNCg0KDQpnbGltcHNlKGgxYl9kYXRhKQ0KDQojd3JpdGUuY3N2KGgxYl9kYXRhLCAiY2xlYW5lZF9kYXRhLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCg0KSSBoYXZlIHBlcmZvcm1lZCBmb2xsb3dpbmcgb3BlcmF0aW9ucyB0byBjbGVhbiB0aGUgZGF0YSBhbmQgbWFrZSBpdCByZWFkeSBmb3IgdGhlIGZ1cnRoZXIgYW5hbHlzaXMuDQoNCi0gSSBzaW1wbGlmaWVkIGFuZCByZW5hbWVkIHRoZSBjb2x1bW5zIHRvIG1ha2UgdGhlbSBjbGVhcmVyIHVzaW5nIHNlbGVjdCgpLiANCg0KLSBJIGFsc28gcmVwbGFjZWQgZW1wdHkgc3RyaW5ncyB3aXRoIE5BIGFuZCBjaGFuZ2VkIGFueSBOQSB2YWx1ZXMgaW4gdGhlIGFwcHJvdmFsL2RlbmlhbCBjb2x1bW5zIHRvIDAgdXNpbmcgbmFfaWYoKSBhbmQgY29hbGVzY2UoKS4NCg0KLSBJIHJlbW92ZWQgcm93cyB3aXRoIG1pc3NpbmcgVGF4X0lEIG9yIEVtcGxveWVyX05hbWUsIGFuZCBhbHNvIHJlbW92ZWQgcm93cyB3aGVyZSBhbGwgdGhlIGFwcHJvdmFsL2RlbmlhbCB2YWx1ZXMgd2VyZSB6ZXJvLg0KDQotIEkgYWRkZWQgbmV3IGNvbHVtbnMgZm9yIHRoZSB0b3RhbCBIMUJzLCBuZXcgSDFCcywgYW5kIHJlbmV3YWwgSDFCcyB1c2luZyBtdXRhdGUoKS4NCg0KDQojIyBGaW5hbCBEYXRhc2V0DQoNCmBgYHtyIGludGVyYWN0aXZlLXRhYmxlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0YXRhYmxlKGgxYl9kYXRhLCANCiAgICAgICAgICBjYXB0aW9uID0gIkZpbmFsIENsZWFuZWQgSC0xQiBFbXBsb3llciBEYXRhIChGWTIwMjQpIiwNCiAgICAgICAgICBvcHRpb25zID1saXN0KHBhZ2VMZW5ndGggPSAxMCwgc2Nyb2xsWCA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIGRlZmVyUmVuZGVyID0gVFJVRSwgc2Nyb2xsZXIgPSBUUlVFKSkNCmBgYA0KDQojIyBWYXJpYWJsZSBEZWZpbml0aW9ucw0KDQotICoqRW1wbG95ZXJfTmFtZSoqIOKAkyBOYW1lIG9mIHRoZSBlbXBsb3llciBzdWJtaXR0aW5nIHRoZSBIMUIgcGV0aXRpb24uDQotICoqVGF4X0lEKiog4oCTIEEgdW5pcXVlIHRheCBpZGVudGlmaWVyIGFzc2lnbmVkIHRvIGVhY2ggZW1wbG95ZXIuDQotICoqTkFDSVNfQ09ERSoqIOKAkyBOb3J0aCBBbWVyaWNhbiBJbmR1c3RyeSBDbGFzc2lmaWNhdGlvbiBTeXN0ZW0gY29kZSBpbmRpY2F0aW5nIHRoZSBpbmR1c3RyeSB0eXBlLg0KLSAqKlBldGl0aW9uZXJfQ2l0eSoqIOKAkyBUaGUgY2l0eSB3aGVyZSB0aGUgcGV0aXRpb25pbmcgZW1wbG95ZXIgaXMgbG9jYXRlZC4NCi0gKipQZXRpdGlvbmVyX1N0YXRlKiog4oCTIFRoZSBVUyBzdGF0ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBlbXBsb3llcuKAmXMgbG9jYXRpb24uDQotICoqUGV0aXRpb25lcl9aaXAqKiDigJMgWklQIGNvZGUgb2YgdGhlIHBldGl0aW9uaW5nIGVtcGxveWVyLg0KLSAqKkluaXRpYWxfQXBwcm92YWwqKiDigJMgTnVtYmVyIG9mIG5ldyBIMUIgdmlzYSBwZXRpdGlvbnMgdGhhdCB3ZXJlIGluaXRpYWxseSBhcHByb3ZlZC4NCi0gKipJbml0aWFsX0RlbmlhbCoqIOKAkyBOdW1iZXIgb2YgbmV3IEgxQiB2aXNhIHBldGl0aW9ucyB0aGF0IHdlcmUgZGVuaWVkLg0KLSAqKkNvbnRpbnVpbmdfQXBwcm92YWwqKiDigJMgTnVtYmVyIG9mIGV4dGVuc2lvbnMgb3IgcmVuZXdhbHMgYXBwcm92ZWQgZm9yIGV4aXN0aW5nIEgxQiB2aXNhcy4NCi0gKipDb250aW51aW5nX0RlbmlhbCoqIOKAkyBOdW1iZXIgb2YgY29udGludWluZyBIMUIgcGV0aXRpb25zIGRlbmllZC4NCi0gKipUb3RhbF9IMUIqKiDigJMgVGhlIHRvdGFsIG51bWJlciBvZiBIMUIgcGV0aXRpb25zIHN1Ym1pdHRlZCAobmV3ICsgcmVuZXdhbHMpLg0KLSAqKlRvdGFsX0xvdHRlcnlfSDFCKiog4oCTIFRvdGFsIGNvdW50IG9mIG5ld2x5IHN1Ym1pdHRlZCBIMUIgcGV0aXRpb25zLg0KLSAqKlRvdGFsX090aGVyKiog4oCTIFRvdGFsIGNvdW50IG9mIEgxQiB2aXNhIGV4dGVuc2lvbnMgb3IgcmVuZXdhbHMgc3VibWl0dGVkLg0KDQojIyBLZXkgVGVybXMNCi0gKipILTFCIFZpc2E6KiogRW1wbG95bWVudCB2aXNhIGZvciBzcGVjaWFsaXplZCBmb3JlaWduIHdvcmtlcnMNCi0gKipIMUIgTG90dGVyeToqKiBUaGUgSC0xQiBsb3R0ZXJ5IGlzIGEgcmFuZG9tIHNlbGVjdGlvbiBwcm9jZXNzIFVTQ0lTIHVzZXMgd2hlbiB0aGUgbnVtYmVyIG9mIGFwcGxpY2F0aW9ucyBmb3IgbmV3IEgtMUIgd29yayB2aXNhcyBleGNlZWRzIHRoZSA4NSwwMDAgYXZhaWxhYmxlIHZpc2Egc2xvdHMuIEJlaW5nIHNlbGVjdGVkIGluIHRoaXMgbG90dGVyeSBpcyBuZWNlc3NhcnkgYmVmb3JlIGFuIGVtcGxveWVyIGNhbiBmb3JtYWxseSBmaWxlIHRoZSBmdWxsIEgtMUIgcGV0aXRpb24gZm9yIGEgY2FwLXN1YmplY3QgZW1wbG95ZWUuDQotICoqSW5pdGlhbCB2cyBDb250aW51aW5nOioqIEluaXRpYWwgYXBwbGljYXRpb25zIHN0YW5kcyBmb3IgbmV3IGFwcGxpY2F0aW9ucyB3aGVyZWFzIGNvbnRpbnVpbmcgYXBwbGljYXRpb25zIGNvbnRhaW5zIGNhc2VzIHdoZW4gcGVvcGxlIGNoYW5nZSBlbXBsb3llcnMsIGFueSBkZXRhaWxzIGV0Yw0KLSAqKlBldGl0aW9uZXI6KiogRW1wbG95ZXIgc3BvbnNvcmluZyB0aGUgdmlzYSBhcHBsaWNhdGlvbg0KLSAqKlRheF9JRDoqKiBUaGUgRW1wbG95ZXIgSWRlbnRpZmljYXRpb24gTnVtYmVyIChFSU4pLCBhIHVuaXF1ZSBpZGVudGlmaWVyIGFzc2lnbmVkIGJ5IHRoZSBJUlMNCi0gKipOQUNJU19DT0RFOioqIE5vcnRoIEFtZXJpY2FuIEluZHVzdHJ5IENsYXNzaWZpY2F0aW9uIFN5c3RlbSBjb2RlLiBUaGlzIG51bWVyaWMgY29kZSBpZGVudGlmaWVzIHRoZSBwcmltYXJ5IGluZHVzdHJ5IHNlY3RvciBvZiB0aGUgZW1wbG95ZXIgKGUuZy4sIFNvZnR3YXJlIFB1Ymxpc2hlcnMsIENvbXB1dGVyIFN5c3RlbXMgRGVzaWduLCBDb2xsZWdlcy9Vbml2ZXJzaXRpZXMpLg0KDQojIyBJbml0aWFsIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KIyMjIE51bWVyaWMgVmFyaWFibGUgQW5hbHlzaXMNCg0KIyMjIyBjZW50ZXIgYW5kIHNwcmVhZCBvZiBOdW1lcmljIHZhcmlhYmxlcw0KDQpgYGB7cn0NCiMgU2VsZWN0IG9ubHkgbnVtZXJpYyB2YXJpYWJsZXMNCm51bV92YXJzIDwtIGgxYl9kYXRhICU+JQ0KICBzZWxlY3QoSW5pdGlhbF9BcHByb3ZhbCwgSW5pdGlhbF9EZW5pYWwsIENvbnRpbnVpbmdfQXBwcm92YWwsDQogICAgICAgICBDb250aW51aW5nX0RlbmlhbCwgVG90YWxfSDFCLCBUb3RhbF9Mb3R0ZXJ5X0gxQiwgVG90YWxfT3RoZXIpDQoNCiMgVXNlIGdldF9zdW1tYXJ5X3N0YXRzIGZyb20gcnN0YXRpeA0Kc3VtbWFyeV9zdGF0cyA8LSBudW1fdmFycyAlPiUNCiAgZ2V0X3N1bW1hcnlfc3RhdHModHlwZSA9ICJmdWxsIikNCg0Kc3VtbWFyeV9zdGF0cyAlPiUNCiAga2FibGUoY2FwdGlvbiA9ICJTdW1tYXJ5IFN0YXRpc3RpY3MgZm9yIE51bWVyaWMgUGV0aXRpb24gQ291bnRzIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJob3ZlciIpLCBmdWxsX3dpZHRoID0gRkFMU0UsICBwb3NpdGlvbiA9ICJjZW50ZXIiKQ0KYGBgDQoNClRoZSBtZWRpYW4gZm9yIG1vc3QgY291bnQgdmFyaWFibGVzIGlzIGxvdywgd2hpbGUgdGhlIG1lYW4gaXMgc2lnbmlmaWNhbnRseSBoaWdoZXIuIFRoZSBzdGFuZGFyZCBkZXZpYXRpb25zIGFuZCB0aGUgSVFSIGFyZSBsYXJnZSByZWxhdGl2ZSB0byB0aGUgbWVkaWFucywgZnVydGhlciBjb25maXJtaW5nIHRoZSB3aWRlIHNwcmVhZCBhbmQgc2tld25lc3MuIFNvIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgc2hvdyBIMUIgcGV0aXRpb24gY291bnRzIGFyZSBzdHJvbmdseSByaWdodC1za2V3ZWQgd2l0aCBhIHdpZGUgc3ByZWFkLiBUaGlzIG1lYW5zIG1vc3QgZW1wbG95ZXJzIGZpbGUgdmVyeSBmZXcgcGV0aXRpb25zLCB3aGlsZSBhIHNtYWxsIG51bWJlciBmaWxlIGV4dHJlbWVseSBoaWdoIHZvbHVtZXMuIFRoZXNlIGhpZ2gtdm9sdW1lIG91dGxpZXJzIGFwcGVhciBnZW51aW5lIGFuZCByZXByZXNlbnQgc2lnbmlmaWNhbnQgSDFCIGFjdGl2aXR5LCBzbyB0aGV5IHNob3VsZCBiZSByZXRhaW5lZCBpbiB0aGUgYW5hbHlzaXMuDQoNCg0KIyMjIyBIaXN0b2dyYW0gZm9yIGVhY2ggbnVtZXJpYyB2YXJpYWJsZQ0KDQpgYGB7ciwgZWRhLWhpc3RvZ3JhbXN9DQoNCm51bWVyaWNfY29scyA8LSBjKCdJbml0aWFsX0FwcHJvdmFsJywgJ0luaXRpYWxfRGVuaWFsJywgJ0NvbnRpbnVpbmdfQXBwcm92YWwnLA0KICAgICAgICAgICAgICAgICAgJ0NvbnRpbnVpbmdfRGVuaWFsJywgJ1RvdGFsX0gxQicsICdUb3RhbF9Mb3R0ZXJ5X0gxQicsICdUb3RhbF9PdGhlcicpDQoNCmgxYl9udW1lcmljX2xvbmcgPC0gaDFiX2RhdGEgJT4lDQogIHNlbGVjdChhbGxfb2YobnVtZXJpY19jb2xzKSkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gZXZlcnl0aGluZygpLCBuYW1lc190byA9ICJWYXJpYWJsZSIsIHZhbHVlc190byA9ICJDb3VudCIpDQoNCiMgSGlzdG9ncmFtcyB3aXRoIGxvZzFwIHNjYWxlDQpnZ3Bsb3QoaDFiX251bWVyaWNfbG9uZywgYWVzKHggPSBDb3VudCArIDEpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAzMCwgZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgbGFiZWxfbG9nKCkgZm9yIGxvZyBheGVzIG9yIHNpbXBseSBsYWJlbF9udW1iZXIoKQ0KICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbG9nKGJhc2UgPSAxMCkpICsNCiAgZmFjZXRfd3JhcCh+IFZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIpICsgIyBTZXBhcmF0ZSBwbG90IGZvciBlYWNoIHZhcmlhYmxlDQogIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtcyBvZiBIMUIgUGV0aXRpb24gQ291bnRzIHBlciBFbXBsb3llciAoTG9nIFNjYWxlKSIsDQogICAgICAgeCA9ICJMb2cxMCBTY2FsZSIsDQogICAgICAgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQpUaGUgaGlzdG9ncmFtcyBjb25maXJtIHRoZSBkaXN0cmlidXRpb25zIGFyZSBoZWF2aWx5IHJpZ2h0LXNrZXdlZC4gRXZlbiBvbiB0aGUgbG9nIHNjYWxlLCB3ZSBzZWUgbW9zdCBvZiB0aGUgZnJlcXVlbmN5IGNvbmNlbnRyYXRlZCB0b3dhcmRzIHRoZSBsb3dlciBjb3VudHMgaS5lIEluIHRoZSBzdW1tYXJ5IGlmIHlvdSBvYnNlcnZlIGZvciBhbGwgY2F0ZWdvcmllcyB0aGUgTWVhbiBpcyBncmVhdGVyIHRoYW4gTWVkaWFucy4gTWVhbnMgbW9zdCBlbXBsb3llcnMgZmlsZSB2ZXJ5IGZldyBIMUIgcGV0aXRpb25zIGJ1dCBhIHNtYWxsZXIgbnVtYmVyIG9mIGVtcGxveWVycyBmaWxlIGEgdmVyeSBsYXJnZSBudW1iZXIgb2YgcGV0aXRpb25zLCBwdWxsaW5nIHRoZSBhdmVyYWdlIHVwLlRoZSB1c2Ugb2YgdGhlIGxvZyBzY2FsZSB3YXMgZXNzZW50aWFsIHRvIHZpc3VhbGl6ZSB0aGlzIGRpc3RyaWJ1dGlvbi4NCg0KDQojIyMjIEJveHBsb3RzIGZvciBlYWNoIG51bWVyaWMgdmFyaWFibGUNCg0KYGBge3IsIGVkYS1ib3hwbG90c30NCmdncGxvdChoMWJfbnVtZXJpY19sb25nLCBhZXMoeCA9IFZhcmlhYmxlLCB5ID0gQ291bnQgKyAxKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJsaWdodGdyZWVuIiwgb3V0bGllci5zaGFwZSA9IDIxLCBvdXRsaWVyLnNpemU9MS41KSArDQogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2coYmFzZSA9IDEwKSkgKyAjIFNjYWxlDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiQm94cGxvdHMgb2YgSDFCIFBldGl0aW9uIENvdW50cyBwZXIgRW1wbG95ZXIgKExvZyBTY2FsZSkiLA0KICAgICAgIHggPSAiUGV0aXRpb24gVHlwZSIsDQogICAgICAgeSA9ICJMb2cxMCBTY2FsZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpKQ0KYGBgDQoNClRoZSBtYWluIGJveCAoSVFSKSBmb3IgZWFjaCB2YXJpYWJsZSBpcyBjb21wcmVzc2VkIG5lYXIgdGhlIGJvdHRvbSwgaW5kaWNhdGluZyB0aGF0IDUwJSBvZiBlbXBsb3llcnMgZmFsbCB3aXRoaW4gYSBuYXJyb3cgcmFuZ2Ugb2YgbG93IGNvdW50cy4gVGhlcmUncyBhIHdpZGUgdmFyaWF0aW9uIGluIEgxQiBmaWxpbmcgYWN0aXZpdHkgYW1vbmcgZW1wbG95ZXJzLiBUaGUgbnVtZXJvdXMgb3V0bGllcnMgcmVwcmVzZW50IGVtcGxveWVycyB3aXRoIGV4Y2VwdGlvbmFsbHkgaGlnaCBwZXRpdGlvbiB2b2x1bWVzIGNvbXBhcmVkIHRvIHRoZSB0eXBpY2FsIGZpbGVyLiBBcyBkaXNjdXNzZWQgYmVmb3JlLCB0aGVzZSBhcmUgdXN1YWxseSBnZW51aW5lIChsaWtlIGxhcmdlIHRlY2ggY29tcGFuaWVzLCBjb25zdWx0aW5nIGZpcm1zLCB1bml2ZXJzaXRpZXMpIGFuZCByZXByZXNlbnQgYSBzaWduaWZpY2FudCBwb3J0aW9uIG9mIHRoZSB0b3RhbCBIMUIgYWN0aXZpdHkuDQoNCiMjIyBDYXRlZ29yaWNhbCBWYXJpYWJsZSBBbmFseXNpcw0KDQojIyMjIEZyZXF1ZW5jeSB0YWJsZSBieSBzdGF0ZQ0KDQpgYGB7ciwgZWRhLWZyZXEtdGFibGUtc3RhdGV9DQoNCmRhdGF0YWJsZShoMWJfZGF0YSAlPiUNCiAgY291bnQoUGV0aXRpb25lcl9TdGF0ZSwgc29ydCA9IFRSVUUpLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGZpbHRlciA9ICd0b3AnLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCkpDQpgYGANCg0KIyMjIyBGcmVxdWVuY3kgdGFibGUgYnkgY2l0eQ0KDQpgYGB7ciwgZWRhLWZyZXEtdGFibGUtY2l0eX0NCg0KZGF0YXRhYmxlKGgxYl9kYXRhICU+JQ0KICBjb3VudChQZXRpdGlvbmVyX0NpdHksIHNvcnQgPSBUUlVFKSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBmaWx0ZXIgPSAndG9wJywNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTApKQ0KYGBgDQoNCiMjIyMgRnJlcXVlbmN5IHRhYmxlIGJ5IFppcGNvZGUNCg0KYGBge3IsIGVkYS1mcmVxLXRhYmxlLVppcH0NCg0KZGF0YXRhYmxlKGgxYl9kYXRhICU+JQ0KICBjb3VudChQZXRpdGlvbmVyX1ppcCwgc29ydCA9IFRSVUUpLA0KICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGZpbHRlciA9ICd0b3AnLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCkpDQpgYGANCg0KIyMjIyBGcmVxdWVuY3kgdGFibGUgYnkgTkFDSVMgY29kZQ0KDQpgYGB7ciwgZWRhLWZyZXEtdGFibGUtbmFjaXN9DQpkYXRhdGFibGUoaDFiX2RhdGEgJT4lDQogIGNvdW50KE5BQ0lTX0NPREUsIHNvcnQgPSBUUlVFKSwNCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBmaWx0ZXIgPSAndG9wJywNCiAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTApKQ0KYGBgDQoNCiMjIyMgUGV0aXRpb25lciBTdGF0ZSBNYXANCg0KYGBge3IgZWRhLXN0YXRlLW1hcCwgb3V0LmhlaWdodD0iNjAwcHgiLCBvdXQud2lkdGg9IjEwMCUifQ0KDQojIENhbGN1bGF0ZSBTdGF0ZSBGcmVxdWVuY2llcw0Kc3RhdGVfZnJlcV9zaW1wbGUgPC0gaDFiX2RhdGEgJT4lDQogIGZpbHRlcighaXMubmEoUGV0aXRpb25lcl9TdGF0ZSkpICU+JSAgICAgICAgIyBFeGNsdWRlIE5BIHN0YXRlcw0KICBjb3VudChQZXRpdGlvbmVyX1N0YXRlLCBzb3J0ID0gVFJVRSwgbmFtZSA9ICJGcmVxdWVuY3kiKSAjIENvdW50IGJ5IHN0YXRlIGFiYnJldmlhdGlvbg0KDQojIEFzc3VtaW5nIFBldGl0aW9uZXJfU3RhdGUgY29udGFpbnMgdGhlIDItbGV0dGVyIGFiYnJldmlhdGlvbg0Kc3RhdGVfZnJlcV9zaW1wbGUgPC0gc3RhdGVfZnJlcV9zaW1wbGUgJT4lDQogIG11dGF0ZShIb3ZlclRleHQgPSBwYXN0ZSgiU3RhdGU6IiwgUGV0aXRpb25lcl9TdGF0ZSwgIjxicj5FbXBsb3llcnM6IiwgRnJlcXVlbmN5KSkNCg0KIyBDcmVhdGUgUGxvdGx5IE1hcA0KDQpnIDwtIGxpc3QoDQogIHNjb3BlID0gJ3VzYScsDQogIHByb2plY3Rpb24gPSBsaXN0KHR5cGUgPSAnYWxiZXJzIHVzYScpLA0KICBzaG93bGFrZXMgPSBGQUxTRQ0KKQ0KDQpmaWdfbWFwX3NpbXBsZSA8LSBwbG90X2x5KA0KICAgIGRhdGEgPSBzdGF0ZV9mcmVxX3NpbXBsZSwgICAgICAjIFVzZSB0aGUgc2ltcGxlIGZyZXF1ZW5jeSB0YWJsZQ0KICAgIHR5cGUgPSAnY2hvcm9wbGV0aCcsDQogICAgbG9jYXRpb25tb2RlID0gJ1VTQS1zdGF0ZXMnLCAgICMgVXNlIGJ1aWx0LWluIHN0YXRlIGJvdW5kYXJpZXMNCiAgICBsb2NhdGlvbnMgPSB+UGV0aXRpb25lcl9TdGF0ZSwgIyBDb2x1bW4gd2l0aCBzdGF0ZSBhYmJyZXZpYXRpb25zDQogICAgeiA9IH5GcmVxdWVuY3ksICAgICAgICAgICAgICAgICMgQ29sdW1uIHdpdGggdmFsdWVzIGZvciBjb2xvcg0KICAgIHptaW4gPSAwLCAgICAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWw6IFNldCBtaW4gdmFsdWUgZm9yIGNvbG9yIHNjYWxlDQogICAgem1heCA9IG1heChzdGF0ZV9mcmVxX3NpbXBsZSRGcmVxdWVuY3ksIG5hLnJtID0gVFJVRSkgKiAxLjEsDQogICAgdGV4dCA9IH5Ib3ZlclRleHQsICAgICAgICAgICAgICMgQ29sdW1uIGZvciBob3ZlciB0ZXh0DQogICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgIGNvbG9yc2NhbGUgPSAnR3JlZW5zJywgICAgICAgICAgIyBDb2xvciBzY2hlbWUNCiAgICByZXZlcnNlc2NhbGUgPSBUUlVFLCANCiAgICBtYXJrZXIgPSBsaXN0KGxpbmUgPSBsaXN0KGNvbG9yID0gdG9SR0IoImdyZXkiKSwgd2lkdGg9MC41KSksDQogICAgY29sb3JiYXIgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBFbXBsb3llcnMiKQ0KICApICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAnTnVtYmVyIG9mIEgxQiBQZXRpdGlvbmluZyBFbXBsb3llcnMgcGVyIFN0YXRlIChGWTIwMjQpJywNCiAgICBnZW8gPSBnLA0KICAgIHdpZHRoID0gODAwLA0KICAgIGhlaWdodCA9IDYwMA0KICApDQoNCmZpZ19tYXBfc2ltcGxlDQpgYGANCg0KDQpUaGUgYWJvdmUgTWFwIHNob3dzIHN0YXRlcyB3aXRoIGZyZXF1ZW5jaWVzIG9mIEgxQiBwZXRpdGlvbnMNCg0KDQojIyMjIFBldGl0aW9uZXIgU3RhdGUgQW5hbHlzaXMNCg0KYGBge3IgZWRhLXN0YXRlLWJhcnN9DQojIENhbGN1bGF0ZSBmcmVxdWVuY3kgb2YgdG9wIE4gc3RhdGVzDQp0b3Bfbl9zdGF0ZXMgPC0gMTUNCnN0YXRlX2ZyZXEgPC0gaDFiX2RhdGEgJT4lDQogIGZpbHRlcighaXMubmEoUGV0aXRpb25lcl9TdGF0ZSkpICU+JSAjIEV4Y2x1ZGUgTkEgc3RhdGVzIGlmIGFueQ0KICBjb3VudChQZXRpdGlvbmVyX1N0YXRlLCBzb3J0ID0gVFJVRSwgbmFtZSA9ICJGcmVxdWVuY3kiKSAlPiUNCiAgaGVhZCh0b3Bfbl9zdGF0ZXMpDQoNCiMgQmFyIGNoYXJ0IG9mIHRvcCBOIHN0YXRlcw0KZ2dwbG90KHN0YXRlX2ZyZXEsIGFlcyh4ID0gcmVvcmRlcihQZXRpdGlvbmVyX1N0YXRlLCAtRnJlcXVlbmN5KSwgeSA9IEZyZXF1ZW5jeSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICJjb3JhbCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zY2FsZXM6OmNvbW1hKEZyZXF1ZW5jeSkpLCB2anVzdD0tMC41LCBzaXplPTMuNSwgY29sb3I9ImJsYWNrIikgKyANCiAgbGFicyh0aXRsZSA9IHBhc3RlKCJUb3AiLCB0b3Bfbl9zdGF0ZXMsICJIMUIgUGV0aXRpb25lciBTdGF0ZXMgKEZZMjAyNCkiKSwNCiAgICAgICB4ID0gIlBldGl0aW9uZXIgU3RhdGUiLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEVtcGxveWVycyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNClRoZSBiYXIgY2hhcnQgc2hvdyB0aGUgc3RhdGVzIHdpdGggdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHVuaXF1ZSBlbXBsb3llcnMgZmlsaW5nIEgxQiBwZXRpdGlvbnMgaW4gRlkyMDI0LiBUaGUgc3RhdGVzIGxpa2UgQ2FsaWZvcm5pYSwgVGV4YXMsIE5ldyBKZXJzZXksIE5ldyBZb3JrLCBhbmQgVmlyZ2luaWEgYXBwZWFyaW5nIGZyZXF1ZW50bHkuDQoNCg0KIyMjIyBQZXRpdGlvbmVyIENpdGllcyBBbmFseXNpcw0KDQpgYGB7ciBlZGEtY2l0eS1iYXJzfQ0KdG9wX25fY2l0aWVzIDwtIDE1DQpjaXR5X2ZyZXEgPC0gaDFiX2RhdGEgJT4lDQogIGZpbHRlcighaXMubmEoUGV0aXRpb25lcl9DaXR5KSkgJT4lICMgRXhjbHVkZSBOQSBjaXRpZXMgaWYgYW55DQogIGNvdW50KFBldGl0aW9uZXJfQ2l0eSwgc29ydCA9IFRSVUUsIG5hbWUgPSAiRnJlcXVlbmN5IikgJT4lDQogIGhlYWQodG9wX25fY2l0aWVzKQ0KDQojIEJhciBjaGFydCBvZiB0b3AgTiBjaXRpZXMNCmdncGxvdChjaXR5X2ZyZXEsIGFlcyh4ID0gcmVvcmRlcihQZXRpdGlvbmVyX0NpdHksIC1GcmVxdWVuY3kpLCB5ID0gRnJlcXVlbmN5KSkgKw0KICBnZW9tX2NvbChmaWxsID0gImRhcmtzZWFncmVlbiIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zY2FsZXM6OmNvbW1hKEZyZXF1ZW5jeSkpLCB2anVzdD0tMC41LCBzaXplPTMuNSwgY29sb3I9ImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gcGFzdGUoIlRvcCIsIHRvcF9uX2NpdGllcywgIkgxQiBQZXRpdGlvbmVyIENpdGllcyAoRlkyMDI0KSIpLA0KICAgICAgIHggPSAiUGV0aXRpb25lciBDaXR5IiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBFbXBsb3llcnMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICMgUm90YXRlIGxhYmVscw0KICANCmBgYCAgDQoNClRoaXMgYW5hbHlzaXMgcmV2ZWFscyB0aGUgc3BlY2lmaWMgY2l0aWVzIHdoZXJlIHRoZSBoaWdoZXN0IG51bWJlciBvZiBlbXBsb3llcnMgZmlsaW5nIEgxQiBwZXRpdGlvbnMgYXJlIGxvY2F0ZWQgaW4gTmV3IFlvcmssIFNhbiBGcmFuY2lzY28sIEhvdXN0b24sIGV0Yw0KDQoNCiMjIyMgUGV0aXRpb25lciBaaXBjb2RlIEFuYWx5c2lzDQoNCmBgYHtyIGVkYS16aXAtYmFyc30NCnRvcF9uX3ppcCA8LSAxNQ0KemlwX2ZyZXEgPC0gaDFiX2RhdGEgJT4lDQogIGZpbHRlcighaXMubmEoUGV0aXRpb25lcl9aaXApKSAlPiUgIyBFeGNsdWRlIE5BIHppcCBjb2RlcyBpZiBhbnkNCiAgbXV0YXRlKFBldGl0aW9uZXJfWmlwID0gYXMuY2hhcmFjdGVyKFBldGl0aW9uZXJfWmlwKSkgJT4lDQogIGNvdW50KFBldGl0aW9uZXJfWmlwLCBzb3J0ID0gVFJVRSwgbmFtZSA9ICJGcmVxdWVuY3kiKSAlPiUNCiAgaGVhZCh0b3Bfbl96aXApDQoNCiMgQmFyIGNoYXJ0IG9mIHRvcCBOIHppcCBjb2Rlcw0KZ2dwbG90KHppcF9mcmVxLCBhZXMoeCA9IHJlb3JkZXIoUGV0aXRpb25lcl9aaXAsIC1GcmVxdWVuY3kpLCB5ID0gRnJlcXVlbmN5KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIm1lZGl1bXB1cnBsZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zY2FsZXM6OmNvbW1hKEZyZXF1ZW5jeSkpLCB2anVzdD0tMC41LCBzaXplPTMuNSwgY29sb3I9ImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gcGFzdGUoIlRvcCIsIHRvcF9uX3ppcCwgIkgxQiBQZXRpdGlvbmVyIFppcCBDb2RlcyAoRlkyMDI0KSIpLA0KICAgICAgIHggPSAiUGV0aXRpb25lciBaaXAgQ29kZSIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZXJzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0PTAuNSkpDQpgYGAgIA0KDQpUaGUgdG9wIHppcCBjb2RlcyBvZnRlbiBwb2ludHMgdG8gc3BlY2lmaWMgY29ycG9yYXRlIGNhbXB1c2VzLCBvZmZpY2UgcGFya3MsIG9yIHVuaXZlcnNpdHkgYXJlYXMga25vd24gZm9yIGhpZ2ggY29uY2VudHJhdGlvbnMgb2YgSDFCIGVtcGxveWVycy4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCBzZWUgemlwIGNvZGVzIGFzc29jaWF0ZWQgd2l0aCBtYWpvciB0ZWNoIGNvbXBhbnkgaGVhZHF1YXJ0ZXJzIG9yIGxhcmdlIGNvbnN1bHRpbmcgZmlybSBvZmZpY2VzIGFwcGVhcmluZyBmcmVxdWVudGx5Lg0KDQoNCiMjIyMgTkFJQ1MgY29kZXMgQW5hbHlzaXMNCg0KYGBge3IgZWRhLW5haWNzLWJhcnMsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMCwgb3V0LndpZHRoPSIxMDAlIn0NCiMgQ2FsY3VsYXRlIGZyZXF1ZW5jeSBvZiB0b3AgTiBOQUlDUyBjb2Rlcw0KdG9wX25fbmFpY3MgPC0gMTUNCm5haWNzX2ZyZXEgPC0gaDFiX2RhdGEgJT4lDQogIGZpbHRlcighaXMubmEoTkFDSVNfQ09ERSkpICU+JSAjIEV4Y2x1ZGUgTkEgY29kZXMgaWYgYW55DQogICMgRW5zdXJlIE5BQ0lTX0NPREUgaXMgdHJlYXRlZCBhcyBjaGFyYWN0ZXIvZmFjdG9yIGZvciBjb3VudGluZw0KICBtdXRhdGUoTkFDSVNfQ09ERSA9IGFzLmNoYXJhY3RlcihOQUNJU19DT0RFKSkgJT4lDQogIGNvdW50KE5BQ0lTX0NPREUsIHNvcnQgPSBUUlVFLCBuYW1lID0gIkZyZXF1ZW5jeSIpICU+JQ0KICBoZWFkKHRvcF9uX25haWNzKQ0KDQojIEJhciBjaGFydCBvZiB0b3AgTiBOQUlDUyBjb2Rlcw0KZ2dwbG90KG5haWNzX2ZyZXEsIGFlcyh4ID0gcmVvcmRlcihOQUNJU19DT0RFLCBGcmVxdWVuY3kpLCB5ID0gRnJlcXVlbmN5KSkgKw0KICBnZW9tX2NvbChmaWxsID0gInN0ZWVsYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KA0KICAgIGFlcyhsYWJlbCA9IHNjYWxlczo6Y29tbWEoRnJlcXVlbmN5KSksDQogICAgaGp1c3Q9LTAuMSwNCiAgICBjb2xvciA9ICJibGFjayIsDQogICAgc2l6ZSA9IDMNCiAgKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZSgiVG9wIDE1IEgxQiBQZXRpdGlvbmVyIEluZHVzdHJpZXMgKE5BSUNTIENvZGVzLCBGWTIwMjQpIiksDQogICAgICAgeCA9ICJOQUlDUyBDb2RlIiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBFbXBsb3llcnMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KVGhlIGNoYXJ0IHNob3cgdGhlIG1vc3QgZnJlcXVlbnQgTkFJQ1MgY29kZXMgYXNzb2NpYXRlZCB3aXRoIGVtcGxveWVycyBmaWxpbmcgSDFCIHBldGl0aW9ucy4gQ29kZXMgcmVsYXRlZCB0byBJVCBzZXJ2aWNlcyAobGlrZSBDdXN0b20gQ29tcHV0ZXIgUHJvZ3JhbW1pbmcgU2VydmljZXMgLSBvZnRlbiA1NDE1MTEsIENvbXB1dGVyIFN5c3RlbXMgRGVzaWduIFNlcnZpY2VzIC0gNTQxNTEyKSwgU29mdHdhcmUgUHVibGlzaGluZyAoNTExMjEwKSwgTWFuYWdlbWVudCBDb25zdWx0aW5nICg1NDE2MTEpLCBhbmQgcG90ZW50aWFsbHkgaGlnaGVyIGVkdWNhdGlvbiBvciByZXNlYXJjaCBvZnRlbiBkb21pbmF0ZS4gQWxzbyBzdXJwcmlzaW5nbHkgdGhlcmUgYXJlIGxvdCBvZiBlbXBsb3llcnMoaXQgcmFua3Mgb24gN3RoIHBvc2l0aW9uKSB3aG8gZG9lc24ndCBoYXZlIHRoZSBOQUlDUyBjb2RlIG9yIGl0IGlzIG1pc3NpbmcgaW4gdGhlIGlucHV0IHJhdyBkYXRhDQoNCkZvciBtb3JlIGRldGFpbHMgcmVsYXRlZCB0byBOQUlDUyBjb2RlLSBodHRwczovL3d3dy5jZW5zdXMuZ292L25haWNzLw0KDQoNCiMgQW5hbHlzaXMNCg0KDQpJIGFtIGFuYWx5emluZyB0aGUgSDFCIEZZMjAyNCBkYXRhIHRvIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlbGF0aW9uIGJldHdlZW4gdGhlIHNpemUgb2YgdGhlIHBldGl0aW9uaW5nIGNvbXBhbnkgYW5kIHRoZSBvdXRjb21lIG9mICppbml0aWFsKiBIMUIgcGV0aXRpb25zIChBcHByb3ZhbCB2cy4gRGVuaWFsKS4NCg0KQ29tcGFueSBzaXplIGlzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGRhdGEgc2V0IHNvIEknbSBhc3N1bWluZyB0aGUgKip0b3RhbCBudW1iZXIgb2YgaW5pdGlhbCBIMUIgcGV0aXRpb25zIGZpbGVkKiogYnkgZWFjaCB1bmlxdWUgZW1wbG95ZXIgYXMgYW4gaWRlbnRpZmllciB0byBkZWNpZGUgdGhlIGNvbXBhbnkgc2l6ZS4gV2Ugd2lsbCBjYXRlZ29yaXplIGVtcGxveWVycyBiYXNlZCBvbiB3aGV0aGVyIHRoZXkgYXJlIGFib3ZlIG9yIGJlbG93IHRoZSBtZWRpYW4gbnVtYmVyIG9mIHBldGl0aW9ucyBmaWxlZCBhbmQgdXNlIGEgQ2hpLXNxdWFyZWQgdGVzdCBvZiBpbmRlcGVuZGVuY2UgdG8gY29tcGFyZSBhcHByb3ZhbCByYXRlcyBiZXR3ZWVuIHRoZXNlIGdyb3Vwcy4NCg0KYGBge3IgYW5hbHlzaXMtcHJlcCwgcmVzdWx0cz0nYXNpcyd9DQojIENhbGN1bGF0ZSB0aGUgbWVkaWFuIG51bWJlciBvZiBpbml0aWFsIHBldGl0aW9ucyBwZXIgZW1wbG95ZXINCm1lZGlhbl9wZXRpdGlvbnMgPC0gbWVkaWFuKGgxYl9kYXRhJFRvdGFsX0xvdHRlcnlfSDFCLCBuYS5ybSA9IFRSVUUpDQoNCmgxYl9kYXRhIDwtIGgxYl9kYXRhICU+JQ0KICAgICAgbXV0YXRlKFNpemVfQ2F0ZWdvcnkgPSBpZmVsc2UoVG90YWxfTG90dGVyeV9IMUIgPiBtZWRpYW5fcGV0aXRpb25zLCAiTGFyZ2UgRmlsZXIiLCAiU21hbGwgRmlsZXIiKSkNCg0KDQprYWJsZSh0YWJsZShoMWJfZGF0YSRTaXplX0NhdGVnb3J5KSwgY2FwdGlvbiA9ICJOdW1iZXIgb2YgRW1wbG95ZXJzIHBlciBTaXplIENhdGVnb3J5IikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLA0KICAgICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiKQ0KDQpzaXplX2NvbXBhcmlzb25fZGF0YSA8LSBoMWJfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoU2l6ZV9DYXRlZ29yeSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBUb3RhbF9Jbml0aWFsX0FwcHJvdmVkID0gc3VtKGBJbml0aWFsX0FwcHJvdmFsYCwgbmEucm0gPSBUUlVFKSwNCiAgICBUb3RhbF9Jbml0aWFsX0RlbmllZCA9IHN1bShgSW5pdGlhbF9EZW5pYWxgLCBuYS5ybSA9IFRSVUUpLA0KICAgIC5ncm91cHMgPSAnZHJvcCcNCiAgKSAlPiUNCiAgbXV0YXRlKFNpemVfQ2F0ZWdvcnkgPSBmYWN0b3IoU2l6ZV9DYXRlZ29yeSwgbGV2ZWxzID0gYygiU21hbGwgRmlsZXIiLCAiTGFyZ2UgRmlsZXIiKSkpICU+JQ0KICBhcnJhbmdlKFNpemVfQ2F0ZWdvcnkpDQoNCmthYmxlKHNpemVfY29tcGFyaXNvbl9kYXRhLCBjYXB0aW9uID0gIkFnZ3JlZ2F0ZWQgQ291bnRzIGZvciBDaGktc3F1YXJlZCBUZXN0IikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLA0KICAgICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJjZW50ZXIiKQ0KYGBgDQoNCkZyb20gdGhlIG1lZGlhbiwgd2UgZ290IHRvIGtub3cgdGhlcmUgYXJlIDEzMDA0IExhcmdlIGZpbGVycyhCaWcgQ29tcGFuaWVzLCB1bml2ZXJzaXRpZXMgZXRjKSBhbmQgMzk3NzEgc21hbGxlciBmaWxlcnMoU3RhcnQgdXBzLCBOZXdseSBlbnRlcmVkIGludG8gSDFCJ3MpDQoNCg0KIyMgQ2hpLXNxdWFyZWQgVGVzdCBvZiBJbmRlcGVuZGVuY2UNCg0KV2UgcGVyZm9ybSB0aGUgQ2hpLXNxdWFyZWQgdGVzdCB0byBkZXRlcm1pbmUgaWYgdGhlcmUncyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgY29tcGFueSBzaXplIGNhdGVnb3J5IGFuZCB0aGUgaW5pdGlhbCBwZXRpdGlvbiBvdXRjb21lLg0KDQoqKkh5cG90aGVzZXM6KioNCg0KLSAqKkjigoA6KiogVGhlIGluaXRpYWwgcGV0aXRpb24gb3V0Y29tZSAoQXBwcm92YWwvRGVuaWFsKSBpcyBpbmRlcGVuZGVudCBvZiB0aGUgY29tcGFueSBzaXplIGNhdGVnb3J5Lg0KLSAqKkjigoE6KiogVGhlIGluaXRpYWwgcGV0aXRpb24gb3V0Y29tZSAoQXBwcm92YWwvRGVuaWFsKSBpcyBkZXBlbmRlbnQgb24gdGhlIGNvbXBhbnkgc2l6ZSBjYXRlZ29yeS4NCg0KDQoqKkFzc3VtcHRpb25zOioqDQoNCi0gKipDYXRlZ29yaWNhbCBEYXRhOioqIGBTaXplX0NhdGVnb3J5YCAoU21hbGwvTGFyZ2UgRmlsZXIpIGFuZCBgT3V0Y29tZWAgKEFwcHJvdmFsL0RlbmlhbCkuDQotICoqSW5kZXBlbmRlbmNlIG9mIE9ic2VydmF0aW9uczoqKiBBc3N1bWVkIGZvciBlYWNoIHBldGl0aW9uLg0KLSAqKkV4cGVjdGVkIENlbGwgQ291bnRzOioqIEFsbCBleHBlY3RlZCBmcmVxdWVuY2llcyBzaG91bGQgYmUg4omlIDUuDQoNCg0KYGBge3IgY2hpX3NxdWFyZWRfdGVzdH0NCiMgQ3JlYXRlIHRoZSBjb250aW5nZW5jeSB0YWJsZQ0KY29udGluZ2VuY3lfdGFibGUgPC0gc2l6ZV9jb21wYXJpc29uX2RhdGEgJT4lDQogIHNlbGVjdChUb3RhbF9Jbml0aWFsX0FwcHJvdmVkLCBUb3RhbF9Jbml0aWFsX0RlbmllZCkgJT4lDQogIGFzLm1hdHJpeCgpDQoNCnJvd25hbWVzKGNvbnRpbmdlbmN5X3RhYmxlKSA8LSBzaXplX2NvbXBhcmlzb25fZGF0YSRTaXplX0NhdGVnb3J5DQoNCiMgUGVyZm9ybSB0aGUgQ2hpLXNxdWFyZWQgdGVzdA0KIyBVc2luZyBzaW11bGF0ZS5wLnZhbHVlID0gVFJVRSBpcyBzYWZlciBpZiBjb3VudHMgbWlnaHQgYmUgbG93IGluIHNvbWUgY2VsbHMNCg0KY2hpX3Rlc3RfcmVzdWx0IDwtIGNoaXNxLnRlc3QoY29udGluZ2VuY3lfdGFibGUsIHNpbXVsYXRlLnAudmFsdWUgPSBUUlVFLCBCID0gNTAwMCkNCg0KcHJpbnQoY2hpX3Rlc3RfcmVzdWx0KQ0KcHJpbnQoY2hpX3Rlc3RfcmVzdWx0JGV4cGVjdGVkKQ0KDQphc3N1bXB0aW9uX21ldCA8LSBhbGwoY2hpX3Rlc3RfcmVzdWx0JGV4cGVjdGVkID49IDUpDQoNCmNhdChwYXN0ZSgiXG5Bc3N1bXB0aW9uIENoZWNrOiBBcmUgYWxsIGV4cGVjdGVkIGNvdW50cyA+PSA1PyIsIGFzc3VtcHRpb25fbWV0LCAiXG4iKSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZWQgdGVzdCByZXN1bHRzIGJhc2VkIG9uIHRoZSBwLXZhbHVlIGFuZCBzaWduaWZpY2FuY2UgbGV2ZWwgKGFscGhhPTAuMDUpLg0KDQoqKkRlY2lzaW9uOioqIFNpbmNlIHRoZSBwLXZhbHVlICggMmUtMDQgKSBpcyBsZXNzIHRoYW4gYWxwaGEgKCAwLjA1ICksIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIChI4oKAKS4NCg0KKipDb25jbHVzaW9uOioqIA0KDQpUaGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgY29tcGFueSBzaXplIGNhdGVnb3J5IChTbWFsbCBGaWxlciB2cy4gTGFyZ2UgRmlsZXIsIGJhc2VkIG9uIHBldGl0aW9uIHZvbHVtZSkgYW5kIHRoZSBpbml0aWFsIEgxQiBwZXRpdGlvbiBvdXRjb21lIChBcHByb3ZhbC9EZW5pYWwpIGF0IHRoZSA1JSBzaWduaWZpY2FuY2UgbGV2ZWwuDQoNClRoZSBhbmFseXNpcyBzdWdnZXN0cyB0aGF0IHRoZSBsaWtlbGlob29kIG9mIGFuIGluaXRpYWwgSDFCIHBldGl0aW9uIGJlaW5nIGFwcHJvdmVkIGRpZmZlcnMgc2lnbmlmaWNhbnRseSBiZXR3ZWVuIGNvbXBhbmllcyBmaWxpbmcgZmV3ZXIgcGV0aXRpb25zICg8PSAxLCAnU21hbGwgRmlsZXJzJykgYW5kIHRob3NlIGZpbGluZyBtb3JlICgnPiAxJywgJ0xhcmdlIEZpbGVycycpLg0KDQpUaGlzIGluZGljYXRlcyB0aGF0IGNvbXBhbmllcyBmaWxpbmcgYSBsYXJnZXIgdm9sdW1lIG9mIGluaXRpYWwgSDFCIHBldGl0aW9ucyB0ZW5kIHRvIGhhdmUgYSBoaWdoZXIgYXBwcm92YWwgcmF0ZSBjb21wYXJlZCB0byB0aG9zZSBmaWxpbmcgZmV3ZXIgcGV0aXRpb25zLg0KDQoNCiMgU3VtbWFyeQ0KDQpUaGlzIHByb2plY3QgYW5hbHl6ZWQgSC0xQiB2aXNhIHBldGl0aW9uIGRhdGEgZm9yIEZZIDIwMjQgdG8gdW5kZXJzdGFuZCBjdXJyZW50IHRyZW5kcyBpbiBlbXBsb3llciBzcG9uc29yc2hpcCwgZm9jdXNpbmcgb24gaWRlbnRpZnlpbmcgd2hpY2ggdHlwZXMgb2YgY29tcGFuaWVzIGFuZCBsb2NhdGlvbnMgYXJlIG1vc3QgYWN0aXZlIGFuZCB3aGV0aGVyIGNvbXBhbnkgc2l6ZSByZWxhdGVzIHRvIHBldGl0aW9uIHN1Y2Nlc3MuDQoNCioqS2V5IEZpbmRpbmdzOioqDQoNCi0gSC0xQiBwZXRpdGlvbmluZyBhY3Rpdml0eSBpcyBtb3JlIGluIHNwZWNpZmljIHN0YXRlcywgd2l0aCBDYWxpZm9ybmlhLCBUZXhhcywgTmV3IEplcnNleSwgTmV3IFlvcmssIGFuZCBWaXJnaW5pYSBzaG93aW5nIHRoZSBoaWdoZXN0IG51bWJlciBvZiB1bmlxdWUgZW1wbG95ZXJzIGZpbGluZyBwZXRpdGlvbnMuIE1ham9yIG1ldHJvcG9saXRhbiBhcmVhcyB3aXRoaW4gdGhlc2Ugc3RhdGVzIGFyZSBob3RzcG90cy4NCg0KLSBJbmR1c3RyaWVzIHJlbGF0ZWQgdG8gSW5mb3JtYXRpb24gVGVjaG5vbG9neSBhcmUgb3ZlcndoZWxtaW5nbHkgdGhlIG1vc3QgY29tbW9uIHNlY3RvcnMgZm9yIGVtcGxveWVycyBmaWxpbmcgSC0xQiBwZXRpdGlvbnMuDQoNCi0gT3VyIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGludmVzdGlnYXRlZCB3aGV0aGVyIHRoZSBudW1iZXIgb2YgcGV0aXRpb25zIGEgY29tcGFueSBmaWxlcyAodXNlZCBhcyBhbiBpbmRpY2F0b3Igb2YgaXRzIHNpemUgb3IgSC0xQiBhY3Rpdml0eSBsZXZlbCkgaXMgcmVsYXRlZCB0byBpdHMgc3VjY2VzcyBpbiBnZXR0aW5nIGluaXRpYWwgcGV0aXRpb25zIGFwcHJvdmVkLiBXZSBmb3VuZCBDb21wYW5pZXMgdGhhdCBmaWxlZCBhIGxhcmdlciBudW1iZXIgb2YgaW5pdGlhbCBILTFCIHBldGl0aW9ucyAoY2xhc3NpZmllZCBhcyAnTGFyZ2UgRmlsZXJzJyBiYXNlZCBvbiBmaWxpbmcgbW9yZSB0aGFuIHRoZSBtZWRpYW4gbnVtYmVyKSBnZW5lcmFsbHkgaGFkIGEgaGlnaGVyIGluaXRpYWwgYXBwcm92YWwgcmF0ZSBjb21wYXJlZCB0byBjb21wYW5pZXMgZmlsaW5nIGZld2VyIHBldGl0aW9ucyAoJ1NtYWxsIEZpbGVycycpLg0KDQotIFRoaXMgc3VnZ2VzdHMgdGhhdCBlbXBsb3llcnMgd2l0aCBoaWdoZXIgSC0xQiBwZXRpdGlvbiB2b2x1bWVzIHRlbmQgdG8gZXhwZXJpZW5jZSBncmVhdGVyIHN1Y2Nlc3MgcmF0ZXMgZm9yIHRoZWlyIGluaXRpYWwgYXBwbGljYXRpb25zLCBhbHRob3VnaCB0aGUgZGlmZmVyZW5jZSBpbiBwZXJjZW50YWdlIHBvaW50cyBtaWdodCBiZSByZWxhdGl2ZWx5IHNtYWxsLg0KDQoqKkxpbWl0YXRpb25zOioqDQoNCi0gQSBrZXkgbGltaXRhdGlvbiB3YXMgdXNpbmcgdGhlIG51bWJlciBvZiBwZXRpdGlvbnMgZmlsZWQgYXMgYSBwcm94eSBmb3IgYWN0dWFsIGNvbXBhbnkgc2l6ZS4gV2hpbGUgaXRzIHJlbGF0ZWQsIHRoaXMgaXNuJ3QgYSBwZXJmZWN0IG1lYXN1cmUuIEEgY29tcGFueSBjb3VsZCBmaWxlIG1hbnkgcGV0aXRpb25zIGJ1dCBzdGlsbCBiZSByZWxhdGl2ZWx5IHNtYWxsLCBvciB2aWNlLXZlcnNhLg0KDQotIEVtcGxveWVyIElkZW50aWZpY2F0aW9uOiBHcm91cGluZyBkYXRhIHJlbGllZCBvbiBlbXBsb3llciBuYW1lcy4gTWlub3IgZGlmZmVyZW5jZXMgaW4gaG93IG5hbWVzIHdlcmUgcmVjb3JkZWQgY291bGQgcG90ZW50aWFsbHkgc3BsaXQgYSBzaW5nbGUgY29tcGFueSBpbnRvIG11bHRpcGxlIGVudHJpZXMsIHNsaWdodGx5IGFmZmVjdGluZyBjb3VudHMoRVg6IEFNQVpPTiBERVZFTE9QTUVOVCBDRU5URVIgVSBTIElOQywgQU1BWk9OIERBVEEgU0VSVklDRVMgSU5DLCBBTUFaT04gQ09NIFNFUlZJQ0VTIExMQyBldGMpDQoNCi0gVGhpcyBhbmFseXNpcyBpcyBhIHNuYXBzaG90IGJhc2VkIG9uIEZZMjAyNCBkYXRhLiBJdCBkb2Vzbid0IHNob3cgdHJlbmRzIG92ZXIgbXVsdGlwbGUgeWVhcnMgb3IgcHJvdmlkZSByZWFzb25zIHdoeSBwZXRpdGlvbnMgd2VyZSBhcHByb3ZlZCBvciBkZW5pZWQuDQoNCioqTmV4dCBTdGVwczoqKg0KDQotIElmIHBvc3NpYmxlLCBhZGRpbmcgdGhlIGNvbXBhbnkgZW1wbG95ZWUgY291bnRzIGNvdWxkIHByb3ZpZGUgYSBtb3JlIGFjY3VyYXRlIGNvbXBhcmlzb24gYmFzZWQgb24gY29tcGFueSBzaXplLg0KDQotIFJlcGVhdGluZyB0aGUgc2l6ZSB2cy4gYXBwcm92YWwgcmF0ZSBhbmFseXNpcyB3aXRoaW4gc3BlY2lmaWMgZG9taW5hbnQgaW5kdXN0cmllcyAobGlrZSBJVCkgb3Igc3RhdGVzIChsaWtlIENhbGlmb3JuaWEpIGNvdWxkIHJldmVhbCBpZiB0aGlzIHRyZW5kIGhvbGRzIHRydWUgYWNyb3NzIGRpZmZlcmVudCBzZWdtZW50cy4NCg0KLSBJbnZlc3RpZ2F0aW5nIGlmIGEgc2ltaWxhciByZWxhdGlvbnNoaXAgZXhpc3RzIGJldHdlZW4gY29tcGFueSBzaXplL3BldGl0aW9uIHZvbHVtZSBhbmQgdGhlIHN1Y2Nlc3MgcmF0ZSBvZiBjb250aW51aW5nIChyZW5ld2FsKSBwZXRpdGlvbnMuDQoNCi0gdXNpbmcgRlkyMDI0IGFzIHNhbXBsZSwgd2UgY2FuIGRvIHNpbWlsYXIgYW5hbHlzaXMgb24gaGlzdG9yeSBvZiBhbGwgRmlzY2FsIHllYXJzIGRhdGEgdG8gZ2V0IG1vcmUgZmluZGluZ3MuDQoNCiMgUmVmZXJlbmNlcw0KDQotIGh0dHBzOi8vd3d3LnVzY2lzLmdvdi90b29scy9yZXBvcnRzLWFuZC1zdHVkaWVzL2gtMWItZW1wbG95ZXItZGF0YS1odWINCi0gaHR0cHM6Ly9pbWFnZXMuZ29vZ2xlLmNvbS8NCi0gaHR0cHM6Ly93d3cuY2Vuc3VzLmdvdi9uYWljcy8NCi0gaHR0cHM6Ly93d3cueW91dHViZS5jb20vQHN0YXRxdWVzdA0KLSBodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PXJ1bElVQU4wVTN3JnQ9MjYwcw0KDQoNCiMgUGVyc29uYWwgSW5mb3JtYXRpb24NCg0KIVtdKGdrX2hlYWRzaG90LmpwZWcpe3dpZHRoPTI0MHB4IGhlaWdodD0yNDBweH0NCg0KR2VldGhha3Jpc2huYSBQdWxpZ3VuZGxhIChHSykgaXMgZ3JhZHVhdGluZyBpbiBNYXkgMjAyNSB3aXRoIE1hc3RlcnMgaW4gQ29tcHV0ZXIgU2NpZW5jZSBkZWdyZWUuIEhlIGlzIGEgbmVyZCBndXkgbGlrZXMgdG8gd29yayB3aXRoIG51YW5jZWQgdGhpbmdzLiBIZSBsaWtlcyB0byAgZ28gaW50byByYWJiaXQgaG9sZShkZWVwIHJlc2VhcmNoKSBpZiBoZSBmZWVscyBpdHMgZXhjaXRpbmcuIEludGVyZXN0ZWQgdG8gd29yayBvbiB0aGUgYnVpbGRpbmcgbmV3IHByb2R1Y3RzL3NvZnR3YXJlIHRvIG1ha2UgaXQgaGVscGZ1bCBmb3IgdGhlIHNvY2lldHkgYW5kIHN0cml2ZSBmb3IgbWFraW5nIHRoZSB3b3JsZCBhIGJldHRlciBwbGFjZS4gQ3VycmVudGx5IGxvb2tpbmcgZm9yIGEgbmV3IG9wcG9ydHVuaXR5IHRvIHdvcmsgb24gYWZ0ZXIgZ3JhZHVhdGlvbi4NCg0KSGlzIHBoaWxvc29waHkgaXMgdG8gIkJlIGN1cmlvdXMhIFNvbHZlIGhhcmQgcHJvYmxlbXMiDQoNCm1haWw6IHBnZWV0aGFrcmlzaG5hQGdtYWlsLmNvbQ0KDQo=